﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

//A 2d array using bits for storage

namespace SCG.General
{
    public class BitMatrix : BaseMatrix
    {
        //constructor
        public BitMatrix(int width, int height)
        {
            _width = width;
            _height = height;
            _cellsWide = (int)Math.Ceiling(_width / 8.0);
            _buffer = new byte[_cellsWide, _height];
        }

        //get a value
        public bool Get(int x, int y)
        {
            int idx = x / 8;
            int slot = x % 8;
            int value = _buffer[idx, y];
            return (value & _masks[slot]) > 0;
        }

        //set a value
        public void Set(int x, int y, bool on)
        {
            int idx = x / 8;
            int slot = x % 8;
            byte value = _buffer[idx, y];
            if (on)
                _buffer[idx, y] = (byte)(value | _masks[slot]);
            else
                _buffer[idx, y] = (byte)(value & _xorMasks[slot]);
        }
        public bool GetSafely(int x, int y)
        {
            if (InBounds(x, y))
                return Get(x, y);
            else
                return false;
        }
        public void SetSafely(int x, int y, bool on)
        {
            if (InBounds(x, y))
                Set(x, y, on);
        }

        //clear the array
        public void Clear()
        {
            for (int y = 0; y < _height; y++)
                for (int x = 0; x < _cellsWide; x++)
                    _buffer[x, y] = 0;
        }

        //private members
        private int _cellsWide;
        private byte[,] _buffer;
        private static byte[] _masks = { 1, 2, 4, 8, 16, 32, 64, 128 };
        private static byte[] _xorMasks = { 1 ^ 255, 2 ^ 255, 4 ^ 255, 8 ^ 255, 16 ^ 255, 32 ^ 255, 64 ^ 255, 128 ^ 255 };
    }
}
